package com.outstanding.ifml.diff;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

//差异比较
public class Difference {

	
	
	
	
	private List<String> oldIfml;
	private List<String> newIfml;
	private ArrayList<ArrayList<Integer>> rectangle = new ArrayList<ArrayList<Integer>>();
	
	public  Difference(String oldIfml,String newIfml){
		
		
		
		
		
		String[] oldifmls = oldIfml.split("\n");
		this.oldIfml = Arrays.asList(oldifmls);
		String[] newifmls = newIfml.split("\n");
		this.newIfml = Arrays.asList(newifmls);;
	}
	
	
	
	//输出比较内容
	public List<DiffItem> executeDiff(){
		initRectangle();
		println();
		setRectangle();
		println();
		List<DiffItem> list= analyseRectangle();
		return list;
	}



	private void println() {
		
		
	}



	private List<DiffItem> analyseRectangle() {
		int oldSize = this.oldIfml.size() + 1;
		int newSize = this.newIfml.size() + 1;
		int i = oldSize - 1;
		int j = newSize - 1;
		List<DiffItem>  list = new ArrayList<DiffItem>();
		if(i == 0 && j != 0){
			while(true){
				DiffItem item = new DiffItem();
				String oldLine = null;
				String newLine = null;
				oldLine = "_";
				newLine = this.newIfml.get(j - 1);
				item.setDiffType(DiffType.insert);
				item.setOldLiner("");
				item.setNewLiner(newLine);
				list.add(item);
				j --;
				if(j == 0){
					break;
				}
			}
		}else if(i != 0 && j == 0){
			while(true){
				DiffItem item = new DiffItem();
				String oldLine = null;
				String newLine = null;
				oldLine = this.oldIfml.get(i - 1);
				newLine = "_";
				item.setDiffType(DiffType.delete);
				item.setOldLiner(oldLine);
				item.setNewLiner("");
				list.add(item);
				i --;
				if(i == 0){
					break;
				}
			}
		}else if(i == 0 && j == 0){
			DiffItem item = new DiffItem();
			String oldLine = null;
			String newLine = null;
			oldLine = "";
			newLine = "";
			item.setDiffType(DiffType.same);
			item.setOldLiner("");
			item.setNewLiner("");
			list.add(item);
			
		}else{
			while(true){
				DiffItem item = new DiffItem();
				String oldLine = null;
				String newLine = null;
				newLine = this.newIfml.get(j - 1);	
				oldLine = this.oldIfml.get(i - 1);

				if(oldLine.equals(newLine)){
					if(i == 1 && j != 1){
						j -= 1;
						item.setDiffType(DiffType.insert);
						item.setOldLiner("");
						item.setNewLiner(newLine);
						list.add(item);
					}else if(i != 1 && j == 1){
						i -= 1;
						item.setDiffType(DiffType.delete);
						item.setOldLiner(oldLine);
						item.setNewLiner("");
						list.add(item);
						
					}else{
						i -= 1;	
						j -= 1;
						item.setDiffType(DiffType.same);
						item.setOldLiner(oldLine);
						item.setNewLiner(newLine);
						list.add(item);
					}
					
				}
				//如果比较不相同
				else{
					if(i == 1 && j != 1){
						j -= 1;
						item.setDiffType(DiffType.insert);
						item.setOldLiner("");
						item.setNewLiner(newLine);
						list.add(item);
					
					}else if(i != 1 && j == 1){
						i -= 1;
						item.setDiffType(DiffType.delete);
						item.setOldLiner(oldLine);
						item.setNewLiner("");
						list.add(item);
						
					}else{
						
						// e1 为左上的值
						int x1 = i - 1;
						int y1 = j - 1;
						int e1 = rectangle.get(x1).get(y1);
						
						// e2 为上边值
						int x2 = i - 1;
						int y2 = j;
						int e2 = rectangle.get(x2).get(y2);
						
						//e3为左边值
						int x3 = i;
						int y3 = j - 1;
						int e3 = rectangle.get(x3).get(y3);
						
						//这三个值中的最大值，如果e1 = e2，返回e1，    如果 e3 等于 e1和e2的最大数，则返回 e1和e2的最大数
						int e4 = Math.max(Math.max(e1, e2),e3);
						//
						if(e4 == e1){
							i = x1;
							j = y1;
							item.setDiffType(DiffType.update);
							item.setOldLiner(oldLine);
							item.setNewLiner(newLine);
							list.add(item);
						}
						
						else if(e4 == e2){
							i = x2;
							j = y2;
							item.setDiffType(DiffType.delete);
							item.setOldLiner(oldLine);
							item.setNewLiner("");
							list.add(item);
							
						}else if(e4 == e3){
							i = x3;
							j = y3;
							item.setDiffType(DiffType.insert);
							item.setOldLiner("");
							item.setNewLiner(newLine);
							list.add(item);
							
						}
					}
				}
				
				if(i == 0 && j == 0){
					break;
				}
			}	
		}
		return list;
	}


	//其中i是y轴，j是x轴
	private void setRectangle() {
		
		int oldSize = this.oldIfml.size() + 1;
		int newSize = this.newIfml.size() + 1;
		for(int i = 1;i < oldSize;i ++){
			String oldLine = this.oldIfml.get(i - 1);
			for(int j = 1;j < newSize;j ++){
				String newLine = this.newIfml.get(j - 1);
				if(oldLine.equals(newLine)){
					int e = rectangle.get(i - 1).get(j - 1) + 1;
					rectangle.get(i).add(e);
				}else{
					
					//在所有值相等情况下，第一优先取i-1，j-1，第二优先取 i-1，j，最后取i，优先级按照左上角、上边、左边的顺序
					int e = Math.max(Math.max(rectangle.get(i - 1).get(j - 1),
							//上面的值
							rectangle.get(i - 1).get(j)),
							//左边的值
							rectangle.get(i).get(j - 1));
					rectangle.get(i).add(e);
				}
			}
		}
	}



	private void initRectangle() {
		int oldSize = this.oldIfml.size() + 1;
		int newSize = this.newIfml.size() + 1;
		for(int i = 0;i < oldSize;i ++){   //i 是 y 轴
			ArrayList<Integer> horizontal = new ArrayList<Integer>();
			if(i == 0){
				for(int j = 0;j < newSize;j ++){
					horizontal.add(0);   // j 是 x 轴
				}
			}else{
				horizontal.add(0);
			}
			rectangle.add(horizontal);
		}
		
	}
}
